package com.cloudlegal.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudlegal.common.PageQuery;
import com.cloudlegal.common.PageResult;
import com.cloudlegal.entity.SysUser;
import com.cloudlegal.mapper.SysUserMapper;
import com.cloudlegal.service.SysUserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务实现类
 * 
 * @author CloudLegal Team
 * @since 2024-01-01
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    private final PasswordEncoder passwordEncoder;

    public SysUserServiceImpl(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public SysUser getByUsername(String username) {
        return baseMapper.selectByUsername(username);
    }

    @Override
    public SysUser getByEmail(String email) {
        return baseMapper.selectByEmail(email);
    }

    @Override
    public SysUser getByPhone(String phone) {
        return baseMapper.selectByPhone(phone);
    }

    @Override
    public PageResult<SysUser> getUserPage(PageQuery pageQuery, Integer status, Long roleId) {
        Page<SysUser> page = new Page<>(pageQuery.getPage(), pageQuery.getSize());
        IPage<SysUser> result = baseMapper.selectUserPage(page, pageQuery.getKeyword(), status, roleId);
        return PageResult.of(result);
    }

    @Override
    public List<SysUser> getUserList(String keyword, Integer status, Long roleId) {
        return baseMapper.selectUserList(keyword, status, roleId);
    }

    @Override
    public boolean createUser(SysUser user) {
        // 检查用户名是否存在
        if (existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否存在
        if (StringUtils.hasText(user.getEmail()) && existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 检查手机号是否存在
        if (StringUtils.hasText(user.getPhone()) && existsByPhone(user.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }
        
        // 加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        
        // 设置默认状态
        if (user.getStatus() == null) {
            user.setStatus(1);
        }
        
        return save(user);
    }

    @Override
    public boolean updateUser(SysUser user) {
        SysUser existingUser = getById(user.getId());
        if (existingUser == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 检查用户名是否被其他用户使用
        if (!existingUser.getUsername().equals(user.getUsername()) && existsByUsername(user.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 检查邮箱是否被其他用户使用
        if (StringUtils.hasText(user.getEmail()) && 
            !user.getEmail().equals(existingUser.getEmail()) && existsByEmail(user.getEmail())) {
            throw new RuntimeException("邮箱已存在");
        }
        
        // 检查手机号是否被其他用户使用
        if (StringUtils.hasText(user.getPhone()) && 
            !user.getPhone().equals(existingUser.getPhone()) && existsByPhone(user.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }
        
        // 不更新密码字段
        user.setPassword(null);
        
        return updateById(user);
    }

    @Override
    public boolean deleteUser(Long userId) {
        return removeById(userId);
    }

    @Override
    public boolean batchDeleteUsers(List<Long> userIds) {
        return removeByIds(userIds);
    }

    @Override
    public boolean resetPassword(Long userId, String newPassword) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setPassword(passwordEncoder.encode(newPassword));
        return updateById(user);
    }

    @Override
    public boolean changePassword(Long userId, String oldPassword, String newPassword) {
        SysUser user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 验证旧密码
        if (!passwordEncoder.matches(oldPassword, user.getPassword())) {
            throw new RuntimeException("原密码错误");
        }
        
        // 更新新密码
        user.setPassword(passwordEncoder.encode(newPassword));
        return updateById(user);
    }

    @Override
    public boolean updateUserStatus(Long userId, Integer status) {
        SysUser user = new SysUser();
        user.setId(userId);
        user.setStatus(status);
        return updateById(user);
    }

    @Override
    public boolean batchUpdateUserStatus(List<Long> userIds, Integer status) {
        return baseMapper.batchUpdateStatus(userIds, status) > 0;
    }

    @Override
    public boolean updateLastLoginInfo(Long userId, String loginIp) {
        String loginTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        return baseMapper.updateLastLoginInfo(userId, loginTime, loginIp) > 0;
    }

    @Override
    public boolean existsByUsername(String username) {
        return count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername, username)) > 0;
    }

    @Override
    public boolean existsByEmail(String email) {
        return count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getEmail, email)) > 0;
    }

    @Override
    public boolean existsByPhone(String phone) {
        return count(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, phone)) > 0;
    }

    @Override
    public Map<String, Object> getUserStats() {
        Map<String, Object> stats = new HashMap<>();
        stats.put("total", count());
        stats.put("active", baseMapper.countUsers(1));
        stats.put("inactive", baseMapper.countUsers(0));
        return stats;
    }

    @Override
    public Long countUsersByRoleId(Long roleId) {
        return baseMapper.countUsersByRoleId(roleId);
    }

    @Override
    public List<SysUser> getUsersByDeptId(Long deptId) {
        return baseMapper.selectUsersByDeptId(deptId);
    }
}
